#ifndef GAME_ENGINE_H
#define GAME_ENGINE_H

#include <vector>
#include <queue>
#include <string>
#include <utility>
#include <fstream>
#include <filesystem>
#include <iostream>

#include <stdlib.h>
#include <time.h>
#include <graphics.h>
#include <sysinfoapi.h>

#include "../MyTetrisNamespace.h"
#include "Block.h"
#include "Pool.h"

MY_TETRIS_NAMESPACE_BEGIN
static bool IF_INIT_GAME_DATA_FOLDER = false;

static const int MAX_BLOCKS_QUEUE_SIZE = 10;

static const int MAX_REST_DURATION = 800;

static const int USER_OPERATE_INTERVAL = 80;

static const int SINGAL_SCORE = 100;

class GameEngine
{
private:
	std::vector<std::vector<myTetris::Block*>> blocks;
	std::queue<std::vector<myTetris::Block*>> blocks_queue;
	std::queue<int> block_ids_queue;
	myTetris::Pool* pool = nullptr;
	std::vector<int> line_singal_block_counter;
	int line_max_singal_block_count;
	std::vector<myTetris::Block*> cur_landing_block;
	int cur_landing_block_id;
	std::pair<int, int> cur_landing_block_left_up_coordinate;                                                        
	int block_form_index;
	std::vector<std::vector<bool>> overlap_shape;
	bool if_over = false;
	IMAGE* landed_block_skins = nullptr;
	bool if_operating = false;
	std::vector<unsigned long long> timer;
	int block_landing_speed;
	unsigned int score;
public:
	GameEngine(const std::string& block_define_file, const std::string& pool_define_file);
	~GameEngine();
public:
	void draw(const int& x = 0, const int& y = 0);
private:
	void initDir();
	std::vector<std::string> splitData(const std::string& str, const char& ch = ' ');
	unsigned long long getTimeInterval(const int& timer_id);
private:
	void productRandomBlock();
	bool calculateOverlapDepth(const std::vector<std::vector<int>>& pool_shape, const int& pool_margin, const std::vector<std::vector<int>>& block_shape, const int& index_x, const int& index_y);
	void landCurBlock();
	void eliminateFilledLines(std::queue<int>& line_ids);
public:
	void blockLanding();
	void userOperate();
	void run();
	void reset(const std::string& block_define_file, const std::string& pool_define_file);
};
MY_TETRIS_NAMESPACE_END

#endif
